#include "comsetdialog.h"
#include "ui_comsetdialog.h"
#include <QTimer>
#include <QByteArray>
#include <QDebug>
#include <QComboBox>
#include <QIODevice>
#include <QElapsedTimer>
#include <QMessageBox>

bool ComSetDialog::isFirst=true;
ComSetDialog::ComSetDialog(MainWindow* m,QWidget *parent) :
    m_mainWindow(m),DialogBase(parent),
    ui(new Ui::ComSetDialog)
{
    ui->setupUi(this);
    m_PortName=QString();
    m_BuadRate=baudRates[ui->combox_BaudRate->currentIndex()];
    m_DataBit=dataBits[ui->combox_DataBit->currentIndex()];
    m_StopBit=stopBits[ui->combox_StopBit->currentIndex()];
    m_ParityBits=parityBits[ui->combox_CheckBit->currentIndex()];
    m_TimeOutMs=timeout_ms[ui->combox_Timeout->currentIndex()];


    //connect(this,&ComSetDialog::setWindowTittle,ui->widget,&TitleBar::setTittle);
    //emit setWindowTittle("通讯参数配置");
    //m_IsWaitingForResponse=false;

    loadSerialPorts();
    loadSerialPortParams();

//    connect(ui->widget,&TitleBar::requestClose,this,[=](){
//        this->close();
//        emit ComSetDialogClosed();
//    });

}

ComSetDialog::~ComSetDialog()
{
    delete ui;
}

void ComSetDialog::on_combox_SerialPort_activated(const QString &arg1)
{
    //loadSerialPorts();
}



void ComSetDialog::loadSerialPorts() //加载串口端口
{
    ui->combox_SerialPort->clear();
    // 获取串口列表并填充到串口选择框中
    const QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts();
    if(ports.isEmpty())
    {
        m_ports.clear();
        return;
    }
    for (const QSerialPortInfo &info : ports) {
        ui->combox_SerialPort->addItem(info.portName());
        m_ports.append(info.portName());
    }
    connect(ui->combox_SerialPort,
            static_cast<void (QComboBox::*)(const QString &)>(&QComboBox::currentIndexChanged),
            this,
            [=](const QString &text) {
                Utils::m_portName=text;
            });
}


void ComSetDialog::on_Btn_ReadAddress_clicked()
{
    ui->Btn_ReadAddress->setEnabled(false);
    QByteArray arr=Frame_Header;
    arr[Utils::CMD]=0x13;
    arr[Utils::LEN]=0x00;
    m_commands.clear();
    m_commands.append(Utils::calculateChecksum(arr));
    CommandWorker* worker=new CommandWorker();
    QThread* thread=new QThread(this);

    worker->moveToThread(thread);
    connect(worker,&CommandWorker::openFailed,m_mainWindow,&MainWindow::popMessageBox);
    connect(worker,&CommandWorker::OneFrameFinished,m_mainWindow,&MainWindow::appendLog);  //连接主函数显示响应结果
    connect(worker,&CommandWorker::commandResult,this,&ComSetDialog::ParseData);

    connect(thread,&QThread::started,[=](){
        worker->start(m_commands);
    });
    connect(worker, &CommandWorker::allTaskFinished, worker, &QObject::deleteLater);
    connect(worker, &CommandWorker::allTaskFinished, thread, &QThread::quit);
    connect(thread, &QThread::finished, thread, &QObject::deleteLater);
    thread->start();
    connect(worker,&CommandWorker::allTaskFinished,this,[=](){
        ui->Btn_ReadAddress->setEnabled(true);
    });
}

void ComSetDialog::on_Btn_WrtieAddress_clicked()
{
    QString text = ui->lineEdit_Address->text().trimmed(); // 获取去掉空格的内容
    // 检查长度是否为12
    if (text.length() != 12) {
        QMessageBox::information(this,"提示","请检查数据长度");
        return;
    }
    // 检查每一位是否合法
    for (const QChar &ch : text) {
        if (!((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'))) {
            QMessageBox::information(this,"提示","数据格式错误");
            return;
        }
    }
    QByteArray adds=Utils::hexStringToByteArray(text);
    ui->Btn_WrtieAddress->setEnabled(false);
    QByteArray arr=Frame_Header;
    arr[Utils::CMD]=0x15;
    arr[Utils::LEN]=0x06;
    arr.append(Utils::reverseByteArray(adds));
    qDebug()<<QString(arr.toHex(' '));
    Utils::Frameadd33(arr); //加33
    qDebug()<<QString(arr.toHex(' '));
    arr=Utils::calculateChecksum(arr);
    //qDebug()<<QString(arr.toHex(' '));
    m_commands.clear();
    m_commands.append(arr);
    CommandWorker* worker=new CommandWorker();
    QThread* thread=new QThread(this);

    worker->moveToThread(thread);
    connect(worker,&CommandWorker::openFailed,m_mainWindow,&MainWindow::popMessageBox);
    connect(worker,&CommandWorker::OneFrameFinished,m_mainWindow,&MainWindow::appendLog);   //连接主函数显示响应结果
    connect(worker,&CommandWorker::commandResult,this,&ComSetDialog::ParseData);            //处理应答

    connect(thread,&QThread::started,[=](){
        worker->start(m_commands);
    });
    connect(worker, &CommandWorker::allTaskFinished, worker, &QObject::deleteLater);
    connect(worker, &CommandWorker::allTaskFinished, thread, &QThread::quit);
    connect(thread, &QThread::finished, thread, &QObject::deleteLater);
    thread->start();
    connect(worker,&CommandWorker::allTaskFinished,this,[=](){
        ui->Btn_WrtieAddress->setEnabled(true);
    });
}

void ComSetDialog::on_Btn_CommTest_clicked()
{
    ui->Btn_CommTest->setEnabled(false);
    m_commands.clear();

    //第一条命令
    QByteArray test1=Utils::instance()->createCommandFrame(0x11,DI_FactoryVersion,0,QByteArray());
    QByteArray test2=Utils::instance()->createCommandFrame(0x11,DI_MeterNumber,0,QByteArray());

    m_commands.append(test1);
    m_commands.append(test2);

    CommandWorker* worker=new CommandWorker();
    QThread* thread=new QThread(this);

    worker->moveToThread(thread);

    connect(worker,&CommandWorker::openFailed,m_mainWindow,&MainWindow::popMessageBox);
    connect(worker,&CommandWorker::OneFrameFinished,m_mainWindow,&MainWindow::appendLog);   //连接主函数显示响应结果
    connect(worker,&CommandWorker::commandResult,this,&ComSetDialog::ParseData);            //处理应答

    connect(thread,&QThread::started,[=](){
        worker->start(m_commands);
    });
    connect(worker, &CommandWorker::allTaskFinished, worker, &QObject::deleteLater);
    connect(worker, &CommandWorker::allTaskFinished, thread, &QThread::quit);
    connect(thread, &QThread::finished, thread, &QObject::deleteLater);
    thread->start();
    connect(worker,&CommandWorker::allTaskFinished,this,[=](){
        ui->Btn_CommTest->setEnabled(true);
    });
}

void ComSetDialog::ParseData(QByteArray arr)
{
    if(arr.size()< 4+(Utils::Frame::LEN))
    {
        return;
    }
    if(arr.at(0)!=0x68)
    {
        arr.remove(0,4);
    }
    Utils::Framesub33(arr);
    unsigned char cmd=arr.at(Utils::Frame::CMD);
    switch (cmd)
    {
    case 0x93:
    {
        QByteArray sub=Utils::reverseByteArray(arr.mid(Utils::Frame::ADR0,6));
        ui->lineEdit_Address->clear();
        ui->lineEdit_Address->setText(QString(sub.toHex()));
        break;
    }
    case 0x9F:
    {
        if(arr.at(Utils::Frame::LEN)==0x0)
        {
            break;
        }
        break;
    }
    case 0x95:
    {
        if(arr.at(Utils::Frame::LEN)==0x0)
        {
            break;
        }
        break;
    }
    }
}

void ComSetDialog::loadSerialPortParams()
{
    if(isFirst==true)
    {
        //获取串口参数
        m_PortName=ui->combox_SerialPort->currentText();
        m_BuadRate=baudRates[ui->combox_BaudRate->currentIndex()];      //波特率
        m_DataBit=dataBits[ui->combox_DataBit->currentIndex()];         //数据位
        m_StopBit=stopBits[ui->combox_StopBit->currentIndex()];         //停止位
        m_ParityBits=parityBits[ui->combox_CheckBit->currentIndex()];   //校验位
        m_TimeOutMs=timeout_ms[ui->combox_Timeout->currentIndex()];     //超时时间

//        Utils::instance()->setSerialPortName(m_PortName);
        Utils::m_portName=m_PortName;
        Utils::instance()->setSerialBaudRate(m_BuadRate);
        Utils::instance()->setSerialPortParity(m_ParityBits);
        Utils::instance()->setSerialPortDataBit(m_DataBit);
        Utils::instance()->setSerialPortStopBits(m_StopBit);
        Utils::instance()->setTimeOutMs(m_TimeOutMs);
        Utils::instance()->setAddress(QByteArray::fromHex(ui->lineEdit_Address->text().toUtf8()));
        //QString addr=Utils::reverseByteArray(Utils::instance()->getAddress()).toHex();
        //ui->lineEdit_Address->setText(addr);
        isFirst=false;
    }
    else
    {
        //m_PortName=Utils::instance()->getSerialPortName();
        m_PortName=Utils::m_portName;
        ui->combox_SerialPort->setCurrentText(Utils::m_portName);
        m_BuadRate=Utils::instance()->getSerialBaudRate();
        ui->combox_BaudRate->setCurrentIndex(findIndex(baudRates,m_BuadRate));
        m_DataBit=Utils::instance()->getSerialPortDataBits();
        ui->combox_DataBit->setCurrentIndex(findIndex(dataBits,m_DataBit));
        m_StopBit=Utils::instance()->getSerialPortStopBits();
        ui->combox_StopBit->setCurrentIndex(findIndex(stopBits,m_StopBit));
        m_ParityBits=Utils::instance()->getSerialPortParity();
        ui->combox_CheckBit->setCurrentIndex(findIndex(parityBits,m_ParityBits));
        m_TimeOutMs=Utils::instance()->getTimeOutMs();
        ui->combox_Timeout->setCurrentIndex(findIndex(timeout_ms,m_TimeOutMs));
        QString pwd_lev=Utils::instance()->getPwdLevel().toHex();
        ui->combox_PsdLevel->setCurrentIndex(findIndex(pwd_level,pwd_lev));
        QString protName=Utils::m_portName;
        int i;
        for(i=0;i<m_ports.size();i++)
        {
            if(m_ports[i]==protName)
            {
                break;
            }
        }
        ui->combox_SerialPort->setCurrentIndex(i);
    }

}



void ComSetDialog::on_Btn_InFactory_clicked()
{
    ui->Btn_InFactory->setEnabled(false);
    QByteArray arr=Frame_Header;
    arr[Utils::CMD]=0x1F;
    arr[Utils::LEN]=0x03;
    arr.append(DI_InFactory);
    Utils::Frameadd33(arr);
    m_commands.clear();
    m_commands.append(Utils::calculateChecksum(arr));
    CommandWorker* worker=new CommandWorker();
    QThread* thread=new QThread(this);

    worker->moveToThread(thread);

    connect(worker,&CommandWorker::openFailed,m_mainWindow,&MainWindow::popMessageBox);
    connect(worker,&CommandWorker::OneFrameFinished,m_mainWindow,&MainWindow::appendLog);   //连接主函数显示响应结果
    connect(worker,&CommandWorker::commandResult,this,&ComSetDialog::ParseData);            //处理应答

    connect(thread,&QThread::started,[=](){
        worker->start(m_commands);
    });
    connect(worker, &CommandWorker::allTaskFinished, worker, &QObject::deleteLater);
    connect(worker, &CommandWorker::allTaskFinished, thread, &QThread::quit);
    connect(thread, &QThread::finished, thread, &QObject::deleteLater);
    thread->start();
    connect(worker,&CommandWorker::allTaskFinished,this,[=](){
        ui->Btn_InFactory->setEnabled(true);
    });
}

void ComSetDialog::on_Btn_OutFactory_clicked()
{
    ui->Btn_OutFactory->setEnabled(false);
    QByteArray arr=Frame_Header;
    arr[Utils::CMD]=0x1F;
    arr[Utils::LEN]=0x03;
    arr.append(DI_OutFatory);
    Utils::Frameadd33(arr);
    m_commands.clear();
    m_commands.append(Utils::calculateChecksum(arr));
    CommandWorker* worker=new CommandWorker();
    QThread* thread=new QThread(this);

    worker->moveToThread(thread);

    connect(worker,&CommandWorker::openFailed,m_mainWindow,&MainWindow::popMessageBox);
    connect(worker,&CommandWorker::OneFrameFinished,m_mainWindow,&MainWindow::appendLog);   //连接主函数显示响应结果
    connect(worker,&CommandWorker::commandResult,this,&ComSetDialog::ParseData);            //处理应答

    connect(thread,&QThread::started,[=](){
        worker->start(m_commands);
    });
    connect(worker, &CommandWorker::allTaskFinished, worker, &QObject::deleteLater);
    connect(worker, &CommandWorker::allTaskFinished, thread, &QThread::quit);
    connect(thread, &QThread::finished, thread, &QObject::deleteLater);
    thread->start();
    connect(worker,&CommandWorker::allTaskFinished,this,[=](){
        ui->Btn_OutFactory->setEnabled(true);
    });
}

void ComSetDialog::on_Btn_InitMeter_clicked()
{
    ui->Btn_InitMeter->setEnabled(false);
    int timeout=Utils::instance()->getTimeOutMs();
    //先将超时时间设置为5秒
    Utils::instance()->setTimeOutMs(5000);
    QByteArray arr=Frame_Header;
    arr[Utils::CMD]=0x1F;
    arr[Utils::LEN]=0x04;
    arr.append(DI_InitMeter);
    Utils::Frameadd33(arr);
    m_commands.clear();
    m_commands.append(Utils::calculateChecksum(arr));
    CommandWorker* worker=new CommandWorker();
    QThread* thread=new QThread(this);

    worker->moveToThread(thread);

    connect(worker,&CommandWorker::openFailed,m_mainWindow,&MainWindow::popMessageBox);
    connect(worker,&CommandWorker::OneFrameFinished,m_mainWindow,&MainWindow::appendLog);   //连接主函数显示响应结果
    connect(worker,&CommandWorker::commandResult,this,&ComSetDialog::ParseData);            //处理应答

    connect(thread,&QThread::started,[=](){
        worker->start(m_commands);
    });
    connect(worker, &CommandWorker::allTaskFinished, worker, &QObject::deleteLater);
    connect(worker, &CommandWorker::allTaskFinished, thread, &QThread::quit);
    connect(thread, &QThread::finished, thread, &QObject::deleteLater);
    thread->start();
    connect(worker,&CommandWorker::allTaskFinished,this,[=](){
        ui->Btn_InitMeter->setEnabled(true);
        Utils::instance()->setTimeOutMs(timeout);
    });
}

void ComSetDialog::protNameChanged(const QString &arg1)
{
    Utils::m_portName=arg1;
}

//void ComSetDialog::on_combox_SerialPort_currentIndexChanged(const QString &arg1)
//{
//    Utils::m_portName=arg1;
//}

void ComSetDialog::on_combox_BaudRate_currentIndexChanged(int index)
{
    Utils::instance()->setSerialBaudRate(baudRates[index]);
}

void ComSetDialog::on_combox_CheckBit_currentIndexChanged(int index)
{
    Utils::instance()->setSerialPortParity(parityBits[index]);
}

void ComSetDialog::on_combox_StopBit_currentIndexChanged(int index)
{
    Utils::instance()->setSerialPortStopBits(stopBits[index]);
}

void ComSetDialog::on_lineEdit_Password_textChanged(const QString &arg1)
{
    QString tmp=arg1;
    Utils::instance()->setPwd(Utils::stringToBCD(tmp));
}

void ComSetDialog::on_combox_DataBit_currentIndexChanged(int index)
{
    Utils::instance()->setSerialPortDataBit(dataBits[index]);
}

void ComSetDialog::on_combox_PsdLevel_currentIndexChanged(const QString &arg1)
{
    QString tmp=arg1;
    Utils::instance()->setPwdLevel(Utils::stringToBCD(tmp));
}

void ComSetDialog::on_combox_Timeout_currentIndexChanged(const QString &arg1)
{
    QString tmp=arg1;
    Utils::instance()->setTimeOutMs(tmp.toUInt());
}

void ComSetDialog::on_lineEdit_Address_textChanged(const QString &arg1)
{
    QByteArray arr=Utils::instance()->reverseByteArray(QByteArray::fromHex(arg1.toUtf8()));
    Utils::instance()->setAddress(arr);
}


